package com.killers.cold.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.killers.cold.config.FileUploadConfig;
import com.killers.cold.orm.entity.DownloadRecord;
import com.killers.cold.orm.entity.FileInformation;
import com.killers.cold.orm.mapper.DownloadRecordMapper;
import com.killers.cold.orm.mapper.FileMapper;
import com.killers.cold.service.IFileDownloadService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.Date;

/**
 * @author 罗天豪
 * @date 2019/9/9
 */
@Service
public class FileDownloadService extends ServiceImpl<FileMapper, FileInformation> implements IFileDownloadService {

    @Autowired
    private FileMapper fileMapper;

    @Autowired
    private DownloadRecordMapper recordMapper;

    @Autowired
    FileUploadConfig fileUploadConfig;

    private FileInformation fileInformation;


    @Override
    public void getFile(String fileId, String userId, HttpServletResponse httpServletResponse) {
        getFileInformation(fileId);
        FileInformation fileInformation = downloadFile(fileId, httpServletResponse);
        if (!StringUtils.isEmpty(fileInformation)) {
            addDownloadRecord(userId, fileId);
        }
    }

    /**
     * 获取文件全路径
     *
     * @return 路径字符串
     */
    private String getFileFullName() {
        return fileInformation.getFileName() + "." + fileInformation.getFileType();
    }

    /**
     * 获取文件信息
     *
     * @param fileId 文件唯一标识
     */
    private void getFileInformation(String fileId) {
        fileInformation = fileMapper.selectByFileId(fileId);
    }


    /**
     * 获取文件输入流
     *
     * @return 文件输入流
     */
    private FileInputStream getFileInputStream() throws IOException {
        String fileFullName = getFileFullName();
        File file = new File(fileUploadConfig.getPath(), fileFullName);
        return new FileInputStream(file);
    }

    /**
     * 获取输出字节流
     *
     * @param httpServletResponse 响应
     * @return 输出字节流
     * @throws IOException IO异常
     */
    private OutputStream getFileOutputStream(HttpServletResponse httpServletResponse) throws IOException {
        //返回的是json格式，必须要设置ContentType，且它的内容为"application/json;charset=UTF-8"；
        //否者会报  org.springframework.web.HttpMediaTypeNotAcceptableException: Could not find
        //和  trying to resolve exception [org.springframework.web.HttpMediaTypeNotAccepta异常
        httpServletResponse.setContentType("application/json;charset=UTF-8");
        httpServletResponse.setCharacterEncoding("UTF-8");
        String fileName = fileInformation.getFileOriginalName() + "." + fileInformation.getFileType();
        httpServletResponse.setHeader("Content-Disposition", "attachment;fileName=" + java.net.URLEncoder.encode(fileName, "UTF-8"));
        // 设置文件名
        return httpServletResponse.getOutputStream();
    }

    /**
     * 下载文件
     *
     * @param fileId              文件唯一标识
     * @param httpServletResponse 响应
     * @return 所下载文件信息
     */
    private FileInformation downloadFile(String fileId, HttpServletResponse httpServletResponse) {
        byte[] buffer = new byte[1024];
        FileInputStream fileInputStream = null;

        BufferedInputStream bufferedInputStream = null;

        BufferedOutputStream bufferedOutputStream = null;

        OutputStream outputStream = null;
        try {
            fileInputStream = getFileInputStream();
            bufferedInputStream = new BufferedInputStream(fileInputStream);
            outputStream = getFileOutputStream(httpServletResponse);
            bufferedOutputStream = new BufferedOutputStream(outputStream);
            int i = bufferedInputStream.read(buffer);
            while (i != -1) {
                bufferedOutputStream.write(buffer);
                i = bufferedInputStream.read(buffer);
            }
            return fileMapper.selectByFileId(fileId);
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        } finally {
            if (!StringUtils.isEmpty(fileInputStream)) {
                try {
                    fileInputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (!StringUtils.isEmpty(bufferedInputStream)) {
                try {
                    bufferedInputStream.close();

                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (!StringUtils.isEmpty(bufferedOutputStream)){
                try {
                    bufferedOutputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * 插入下载记录
     *
     * @param userId 用户唯一标识
     * @param fileId 文件唯一标识
     */
    private void addDownloadRecord(String userId, String fileId) {
        DownloadRecord record = new DownloadRecord();
        record.setFileId(fileId);
        record.setUserId(userId);
        record.setCreateTime(new Date());
        recordMapper.insert(record);
    }
}
